#include "ActionEventCb.h"
#include "ActionBase.h"
#include "context.h"
#include "util.h"
#include "streamdata.h"
#include "Md5.h"
#include "json.h"
#include "accountmgr.h"
#include "agencyeventmgr.h"
#include "account_service.h"
#include "agency_event_service.h"
#include "match_user_api.pb.h"


using namespace std::placeholders;

const char* sence_valid_invite_cb = "validinvitecb";
const char* sence_invite_cb = "invitecb";
const char* sence_recharge_cb = "rechargecb";
const char* sence_register_cb = "registerCb";



static bool __init__ = ActionEventCb::Init();

bool ActionEventCb::Init()
{
    Ctx.msg_router.BindHttpHandle("post", "/inviteCb", ActionEventCb::HandleInviteCb);
    Ctx.msg_router.BindHttpHandle("post", "/validInviteCb", ActionEventCb::HandleValidInviteCb);
    Ctx.msg_router.BindHttpHandle("post", "/rechargedCb", ActionEventCb::HandleRechargeCb);
    Ctx.msg_router.BindHttpHandle("post", "/registerCb", ActionEventCb::HandleRegisterCb);

    AccountService::Instance()->ListenOnAccountGet(reinterpret_cast<std::uint64_t>(sence_invite_cb), ActionEventCb::OnInviteCbAccountGet);
    AccountService::Instance()->ListenOnAccountGet(reinterpret_cast<std::uint64_t>(sence_valid_invite_cb), ActionEventCb::OnValidInviteCbAccountGet);
    AccountService::Instance()->ListenOnAccountGet(reinterpret_cast<std::uint64_t>(sence_recharge_cb), ActionEventCb::OnRechargeCbAccountGet);    

    AgencyEventService::Instance()->ListenOnAgencyEventGet(reinterpret_cast<std::uint64_t>(sence_recharge_cb), ActionEventCb::OnRechargeCbAgencyEventGet);
    AgencyEventService::Instance()->ListenOnAgencyEventGet(reinterpret_cast<std::uint64_t>(sence_register_cb), ActionEventCb::OnRegisterCbAgencyEventGet);
    return true;
}

void ActionEventCb::Response(std::uint32_t request_id, std::uint64_t request_time, int err_code, const std::string& msg)
{
    Json::Value json;
    json["errorCode"] = err_code;
    json["message"] = msg;
	std::string body = CTools::ToStr(json);
	std::uint64_t response_time = CTools::GetUnixTimeMs();
    std::map<std::string,std::string> heads;
    heads["Content-Type"] = "application/json";
	log_debug("request_id:%u,body:%s,request_time:%lu,response_time:%lu,us_cost:%lu", request_id, body.c_str(), request_time, response_time, response_time-request_time);
    Ctx.msg_router.httpServerBack(request_id, 200, heads, body);
}


void ActionEventCb::HandleInviteCb(HttpData&& data)
{
	std::uint64_t request_time = CTools::GetUnixTimeMs();
    std::int32_t err = 1;
    std::string msg = "";
    do
    {
        log_info("request_id:%d,ip:%s,target:%s,body:%s", data.request_id, data.ip.c_str(), data.target.c_str(), data.body.c_str());

        Json::Value json;
        if (!CTools::FromStr(json, data.body)) { msg="parser json failed"; break; } 
        /*
        reqId:xxxx, agency:xxxx, username:xxxx, parent_username:xxxx, share_type:xxxx 
        */
        if (!json.isMember("agency") || !json["agency"].isString()) { msg="miss agency"; break; } 
        if (!json.isMember("username") || !json["username"].isString()) { msg="miss username"; break; } 
        if (!json.isMember("parent_username") || !json["parent_username"].isString()) { msg="miss parent_username"; break; } 
        if (!json.isMember("share_type") || !json["share_type"].isInt()) { msg="miss share_type"; break; }
        if (!json.isMember("share_code") || !json["share_code"].isString()) { msg="miss share_code"; break; } 
        if (!json.isMember("child_type") || !json["child_type"].isInt()) { msg="miss child_type"; } 

        std::string agency = json["agency"].asString();
        std::string username = json["username"].asString();
        std::string parent_username = json["parent_username"].asString();
        std::string share_code = json["share_code"].asString();
        std::int32_t share_type = json["share_type"].asInt();
        std::int32_t child_type = 0;
        if (json.isMember("child_type") && json["child_type"].isInt())
        {
            child_type = json["child_type"].asInt();
        }
        

        if (agency.empty()) { msg="agency error"; break; }
        if (username.empty()) { msg="username error"; break; }
        if (share_code.empty()) { msg="share_code error"; break; }
        if (parent_username.empty()) { msg="parent_username error"; break; }

        std::uint32_t parent_uid = 0;
        std::uint32_t agency_id = 0;
        std::string target = parent_username;
        stAccount* parent_account = AccountMgr::Instance()->Get(agency, parent_username);
        if (parent_account != nullptr)
        {
            // ��ѯ����������Ϣ
            stAccount* account = AccountMgr::Instance()->Get(agency, username);
            if (account != nullptr)
            {
                RequestInviteCb(account->uid, parent_account->uid, share_type, share_code, account->agency_id, username, request_time, parent_username, child_type);
                err = 0; break;
            }
            else
            {
                target = username;
                parent_uid = parent_account->uid;
                agency_id = parent_account->agency_id;
            }
        }
        // ��ѯ��������Ϣ
        StreamData stream_data;
        StreamDataWriter writer(stream_data);
        writer.WriteInt64(request_time);
        writer.WriteString(agency);
        writer.WriteString(username);
        writer.WriteString(parent_username);
        writer.WriteInt(share_type);
        writer.WriteString(share_code);
        writer.WriteInt(parent_uid);
        writer.WriteInt(agency_id);
        writer.WriteInt(child_type);

        if (!AccountService::Instance()->HandleGetAccount(agency, target, std::move(stream_data.Data()), reinterpret_cast<std::uint64_t>(sence_invite_cb)))
        {
            msg="get account failed";
            break;
        }
        err = 0;
    } while (false);
    if (err != 0)
    {
        log_error("request_id:%d,ip:%s,target:%s,body:%s,err:%d,msg:%s", data.request_id, data.ip.c_str(), data.target.c_str(), data.body.c_str(), err, msg.c_str());
    }
    Response(data.request_id, request_time, err, msg);
}
void ActionEventCb::OnInviteCbAccountGet(std::int32_t err_code, stAccount* account, std::string&& trans)
{
    StreamData stream_data(std::move(trans));
    StreamDataReader reader(stream_data);
    std::uint64_t request_time = reader.ReadInt64();
    std::string agency = reader.ReadString();
    std::string username = reader.ReadString();
    std::string parent_username = reader.ReadString();
    std::int32_t share_type = reader.ReadInt();
    std::string share_code = reader.ReadString();
    std::uint32_t parent_uid = reader.ReadInt();
    std::uint32_t agency_id = reader.ReadInt();
    std::int32_t child_type = reader.ReadInt();
    
    log_debug("err_code:%d,request_time:%llu,agency:%s,username:%s,parent_username:%s,share_type:%d, child_type:%d share_code:%sparent_uid:%u,agency_id:%u"
        , err_code,request_time,agency.c_str(),username.c_str(),parent_username.c_str(),share_type, child_type, share_code.c_str(),parent_uid,agency_id);

    if (parent_uid == 0)  // ������������Ϣ
    {
        if (err_code != 0) { log_error("agency:%s,username:%s,err_code:%d", agency.c_str(), username.c_str(), err_code); return; }
        if (account == nullptr) { log_error("agency:%s,username:%s", agency.c_str(), username.c_str()); return; }
    
        stAccount* child_account = AccountMgr::Instance()->Get(agency, username);  // ��ȡ����������Ϣ
        if (child_account != nullptr)
        {
            RequestInviteCb(child_account->uid, account->uid, share_type, share_code, child_account->agency_id, username,  request_time, parent_username, child_type);
        }
        else
        {
            parent_uid = account->uid;
            agency_id = account->agency_id;
    
            StreamData stream_data;
            StreamDataWriter writer(stream_data);
            writer.WriteInt64(request_time);
            writer.WriteString(agency);
            writer.WriteString(username);
            writer.WriteString(parent_username);
            writer.WriteInt(share_type);
            writer.WriteString(share_code);
            writer.WriteInt(parent_uid);
            writer.WriteInt(agency_id);
            writer.WriteInt(child_type);
    
            if (!AccountService::Instance()->HandleGetAccount(agency, username, std::move(stream_data.Data()), reinterpret_cast<std::uint64_t>(sence_invite_cb)))
            {
                log_error("agency:%s,username:%s, get account failed", agency.c_str(), username.c_str());
            }
        }
    }
    else
    {
        // ������������Ϣ
        if (account == nullptr) 
        { 
            // ����������Ϣȱʧ
            log_error("agency:%s,username:%s,err_code:%d", agency.c_str(), username.c_str(), err_code);
            RequestInviteCb(0, parent_uid, share_type, share_code, agency_id, username, request_time, parent_username, child_type);
        }
        else
        {
            // ����������Ϣ����
            RequestInviteCb(account->uid, parent_uid, share_type, share_code, account->agency_id, username,  request_time, parent_username, child_type);
        }
    }
}
int ActionEventCb::RequestInviteCb(std::uint32_t uid, std::uint32_t parent_uid, const std::int32_t& share_type, 
    const std::string& share_code, std::uint32_t agency_id, const std::string& username, std::uint64_t request_time, const std::string& parent_username, const std::int32_t& child_type)
{
    log_debug("uid:%u,parent_uid:%u,share_type:%d,child_type:%d,share_code:%s request_time:%llu", uid, parent_uid, share_type, child_type, share_code.c_str(),request_time);
    
    unsigned int cmd = match_user::MATCH_USER_MSGID_INVITEE_NOTIFY;
    unsigned short dsttype = SERVER_TYPE_MATCH_USER;
    match_user::UserInviteeNotice notice;
    notice.set_uid(uid);
    notice.set_parent_uid(parent_uid);
    notice.set_share_type(share_type);
    notice.set_share_code(share_code);
    notice.set_agency_id(agency_id);
    notice.set_user_name(username);
    notice.set_parent_user_name(parent_username);
    notice.set_child_type(child_type);
    int ret = Ctx.host->MtSendtoSrv(cmd, dsttype, &notice, parent_uid);
    if (0 != ret)
    {
        log_error("MtSendtoSrv cmd:%u, dst:%u, error:%d,uid:%u,parent_uid:%u,share_type:%d,share_code:%s", cmd, dsttype, ret, uid, parent_uid, share_type,share_code.c_str());
    }
    else
    {
        log_debug("MtSendtoSrv cmd:%u, dst:%u, error:%d,uid:%u,parent_uid:%u,share_type:%d,share_code:%s", cmd, dsttype, ret, uid, parent_uid, share_type,share_code.c_str());
    }
    return 0;
}

















void ActionEventCb::HandleValidInviteCb(HttpData&& data)
{
	std::uint64_t request_time = CTools::GetUnixTimeMs();
    std::int32_t err = 1;
    std::string msg = "";
    do
    {
        log_info("request_id:%d,ip:%s,target:%s,body:%s", data.request_id, data.ip.c_str(), data.target.c_str(), data.body.c_str());

        Json::Value json;
        if (!CTools::FromStr(json, data.body)) { msg="parser json failed"; break; } 
        /*
        reqId:xxxx, agency:xxxx, username:xxxx, parent_username:xxxx, share_type:xxxx 
        */
        if (!json.isMember("agency") || !json["agency"].isString()) { msg="miss agency"; break; } 
        if (!json.isMember("username") || !json["username"].isString()) { msg="miss username"; break; } 
        if (!json.isMember("parent_username") || !json["parent_username"].isString()) { msg="miss parent_username"; break; } 
        if (!json.isMember("share_type") || !json["share_type"].isInt()) { msg="miss share_type"; break; }
        if (!json.isMember("share_code") || !json["share_code"].isString()) { msg="miss share_code"; break; } 

        std::string agency = json["agency"].asString();
        std::string username = json["username"].asString();
        std::string parent_username = json["parent_username"].asString();
        std::string share_code = json["share_code"].asString();
        std::int32_t share_type = json["share_type"].asInt();

        if (agency.empty()) { msg="agency error"; break; }
        if (username.empty()) { msg="username error"; break; }
        if (share_code.empty()) { msg="share_code error"; break; }
        if (parent_username.empty()) { msg="parent_username error"; break; }

        std::uint32_t parent_uid = 0;
        std::uint32_t agency_id = 0;
        std::string target = parent_username;
        stAccount* parent_account = AccountMgr::Instance()->Get(agency, parent_username);
        if (parent_account != nullptr)
        {
            // ��ѯ����������Ϣ
            stAccount* account = AccountMgr::Instance()->Get(agency, username);
            if (account != nullptr)
            {
                RequestValidInviteCb(account->uid, parent_account->uid, share_type, share_code, account->agency_id, username, request_time, parent_username);
                err = 0; break;
            }
            else
            {
                target = username;
                parent_uid = parent_account->uid;
                agency_id = parent_account->agency_id;
            }
        }
        // ��ѯ��������Ϣ
        StreamData stream_data;
        StreamDataWriter writer(stream_data);
        writer.WriteInt64(request_time);
        writer.WriteString(agency);
        writer.WriteString(username);
        writer.WriteString(parent_username);
        writer.WriteInt(share_type);
        writer.WriteString(share_code);
        writer.WriteInt(parent_uid);
        writer.WriteInt(agency_id);

        if (!AccountService::Instance()->HandleGetAccount(agency, target, std::move(stream_data.Data()), reinterpret_cast<std::uint64_t>(sence_valid_invite_cb)))
        {
            msg="get account failed";
            break;
        }
        err = 0;
    } while (false);
    if (err != 0)
    {
        log_error("request_id:%d,ip:%s,target:%s,body:%s,err:%d,msg:%s", data.request_id, data.ip.c_str(), data.target.c_str(), data.body.c_str(), err, msg.c_str());
    }
    Response(data.request_id, request_time, err, msg);
}
void ActionEventCb::OnValidInviteCbAccountGet(std::int32_t err_code, stAccount* account, std::string&& trans)
{
    StreamData stream_data(std::move(trans));
    StreamDataReader reader(stream_data);
    std::uint64_t request_time = reader.ReadInt64();
    std::string agency = reader.ReadString();
    std::string username = reader.ReadString();
    std::string parent_username = reader.ReadString();
    std::int32_t share_type = reader.ReadInt();
    std::string share_code = reader.ReadString();
    std::uint32_t parent_uid = reader.ReadInt();
    std::uint32_t agency_id = reader.ReadInt();
    
    log_debug("err_code:%d,request_time:%llu,agency:%s,username:%s,parent_username:%s,share_type:%d,share_code:%sparent_uid:%u,agency_id:%u"
        , err_code,request_time,agency.c_str(),username.c_str(),parent_username.c_str(),share_type,share_code.c_str(),parent_uid,agency_id);

    if (parent_uid == 0)  // ������������Ϣ
    {
        if (err_code != 0) { log_error("agency:%s,username:%s,err_code:%d", agency.c_str(), username.c_str(), err_code); return; }
        if (account == nullptr) { log_error("agency:%s,username:%s", agency.c_str(), username.c_str()); return; }
    
        stAccount* child_account = AccountMgr::Instance()->Get(agency, username);  // ��ȡ����������Ϣ
        if (child_account != nullptr)
        {
            RequestValidInviteCb(child_account->uid, account->uid, share_type, share_code, child_account->agency_id, username,  request_time, parent_username);
        }
        else
        {
            parent_uid = account->uid;
            agency_id = account->agency_id;
    
            StreamData stream_data;
            StreamDataWriter writer(stream_data);
            writer.WriteInt64(request_time);
            writer.WriteString(agency);
            writer.WriteString(username);
            writer.WriteString(parent_username);
            writer.WriteInt(share_type);
            writer.WriteString(share_code);
            writer.WriteInt(parent_uid);
            writer.WriteInt(agency_id);
    
            if (!AccountService::Instance()->HandleGetAccount(agency, username, std::move(stream_data.Data()), reinterpret_cast<std::uint64_t>(sence_valid_invite_cb)))
            {
                log_error("agency:%s,username:%s, get account failed", agency.c_str(), username.c_str());
            }
        }
    }
    else
    {
        // ������������Ϣ
        if (account == nullptr) 
        { 
            // ����������Ϣȱʧ
            log_error("agency:%s,username:%s,err_code:%d", agency.c_str(), username.c_str(), err_code);
            RequestValidInviteCb(0, parent_uid, share_type, share_code, agency_id, username, request_time, parent_username);
        }
        else
        {
            // ����������Ϣ����
            RequestValidInviteCb(account->uid, parent_uid, share_type, share_code, account->agency_id, username,  request_time, parent_username);
        }
    }
}
int ActionEventCb::RequestValidInviteCb(std::uint32_t uid, std::uint32_t parent_uid, const std::int32_t& share_type, 
    const std::string& share_code, std::uint32_t agency_id, const std::string& username, std::uint64_t request_time, const std::string& parent_username)
{
    log_debug("uid:%u,parent_uid:%u,share_type:%d,share_code:%s request_time:%llu", uid, parent_uid, share_type, share_code.c_str(),request_time);
    
    unsigned int cmd = match_user::MATCH_USER_MSGID_INVITEE_VALID_NOTIFY;
    unsigned short dsttype = SERVER_TYPE_MATCH_USER;
    match_user::UserInviteeValidNotice notice;
    notice.set_uid(uid);
    notice.set_parent_uid(parent_uid);
    notice.set_share_type(share_type);
    notice.set_share_code(share_code);
    notice.set_agency_id(agency_id);
    notice.set_user_name(username);
    notice.set_parent_user_name(parent_username);
    int ret = Ctx.host->MtSendtoSrv(cmd, dsttype, &notice, parent_uid);
    if (0 != ret)
    {
        log_error("MtSendtoSrv cmd:%u, dst:%u, error:%d,uid:%u,parent_uid:%u,share_type:%d,share_code:%s", cmd, dsttype, ret, uid, parent_uid, share_type,share_code.c_str());
    }
    else
    {
        log_debug("MtSendtoSrv cmd:%u, dst:%u, error:%d,uid:%u,parent_uid:%u,share_type:%d,share_code:%s", cmd, dsttype, ret, uid, parent_uid, share_type,share_code.c_str());
    }
    return 0;
}

void ActionEventCb::HandleRechargeCb(HttpData&& data)
{
	std::uint64_t request_time = CTools::GetUnixTimeMs();
    std::int32_t err = 1;
    std::string msg = "";
    do
    {
        log_info("request_id:%d,ip:%s,target:%s,body:%s", data.request_id, data.ip.c_str(), data.target.c_str(), data.body.c_str());

        Json::Value json;
        if (!CTools::FromStr(json, data.body)) { msg="parser json failed"; break; } 
        /*
        reqId:xxxx, agency:xxxx, username:xxxx, amount:xxxx
        */
        if (!json.isMember("agency") || !json["agency"].isString()) { msg="miss agency"; break; } 
        if (!json.isMember("username") || !json["username"].isString()) { msg="miss username"; break; } 
        if (!json.isMember("amount") || !json["amount"].isDouble()) { msg="miss amount"; break; } 
        if (!json.isMember("trans") || !json["trans"].isString()) { msg="miss trans"; break; } 
        if (!json.isMember("extra") || !json["extra"].isDouble()) { msg="miss extra"; break; } 
        if (!json.isMember("isfirst") || !json["isfirst"].isBool()) { msg="miss isfirst"; break; } 
        if (!json.isMember("balance") || !json["balance"].isDouble()) { msg="miss balance"; break; } 

        std::string currency = "";
        if (json.isMember("currency") && json["currency"].isString())
        {
            currency = json["currency"].asString();
        }

        std::string agency = json["agency"].asString();
        std::string username = json["username"].asString();
        double amount = json["amount"].asDouble();
        std::string trans = json["trans"].asString();
        double extra = json["extra"].asDouble();
        bool isfirst = json["isfirst"].asBool();
        double balance = json["balance"].asDouble();

        if (agency.empty()) { msg="agency error"; break; }
        if (username.empty()) { msg="username error"; break; }
        
        stAccount* account = AccountMgr::Instance()->Get(agency, username);
        if (account != nullptr)
        {
            stAgencyEvent* st_agency = AgencyEventMgr::Instance()->Get(account->agency_id);
            if (st_agency != nullptr)
            {
                if ((!currency.empty()) && (0 != currency.compare(st_agency->currency))) { msg="currency error"; break; }
                RequestRechargeCb(account->uid, amount * st_agency->currency_unit_multi, st_agency->currency, trans, request_time, extra * st_agency->currency_unit_multi,
                    account->agency_id, username, isfirst, balance * st_agency->currency_unit_multi);
            }
            else
            {
                StreamData stream_data;
                StreamDataWriter writer(stream_data);
                writer.WriteInt64(request_time);
                writer.Write<double>(amount);
                writer.WriteString(agency);
                writer.WriteString(username);
                writer.WriteString(currency);
                writer.WriteInt(account->uid);
                writer.WriteString(trans);
                writer.Write<double>(extra);
                writer.WriteBool(isfirst);
                writer.Write<double>(balance);
                
                if (!AgencyEventService::Instance()->HandleGetAgencyEvent(account->agency_id, std::move(stream_data.Data()), reinterpret_cast<std::uint64_t>(sence_recharge_cb)))
                {
                    log_error("agency_id:%u,get agency_id failed", account->agency_id);
                    break;
                }
            }
        }
        else
        {
            StreamData stream_data;
            StreamDataWriter writer(stream_data);
            writer.WriteInt64(request_time);
            writer.Write<double>(amount);
            writer.WriteString(agency);
            writer.WriteString(username);
            writer.WriteString(currency);
            writer.WriteString(trans);
            writer.Write<double>(extra);
            writer.WriteBool(isfirst);
            writer.Write<double>(balance);

            if (!AccountService::Instance()->HandleGetAccount(agency, username, std::move(stream_data.Data()), reinterpret_cast<std::uint64_t>(sence_recharge_cb)))
            {
                log_error("agency:%s,username:%s,get account failed",agency.c_str(),username.c_str());
                break;
            }
        }
        err = 0;
    } while (false);
    if (err != 0)
    {
        log_error("request_id:%d,ip:%s,target:%s,body:%s,err:%d,msg:%s", data.request_id, data.ip.c_str(), data.target.c_str(), data.body.c_str(), err, msg.c_str());
    }
    Response(data.request_id, request_time, err, msg);
}
void ActionEventCb::OnRechargeCbAccountGet(std::int32_t err_code, stAccount* account, std::string&& trans)
{
    StreamData stream_data(std::move(trans));
    StreamDataReader reader(stream_data);
    std::uint64_t request_time = reader.ReadInt64();
    double amount = reader.Read<double>();
    std::string agency = reader.ReadString();
    std::string username = reader.ReadString();
    std::string currency = reader.ReadString();
    trans = reader.ReadString();
    double extra = reader.Read<double>();
    bool isfirst = reader.ReadBool();
    double balance = reader.Read<double>();

    log_debug("err_code:%d,request_time:%llu,agency:%s,username:%s,amount:%f,currency:%s,extra:%f,isfirst:%d,balance:%f"
        , err_code,request_time,agency.c_str(),username.c_str(),amount,currency.c_str(),extra,isfirst,balance);

    if (err_code != 0) { log_error("agency:%s,username:%s,err_code:%d", agency.c_str(), username.c_str(), err_code); return; }
    if (account == nullptr) { log_error("agency:%s,username:%s", agency.c_str(), username.c_str()); return; }

    stAgencyEvent* st_agency = AgencyEventMgr::Instance()->Get(account->agency_id);
    if (st_agency != nullptr)
    {
        if ((!currency.empty()) && (0 != currency.compare(st_agency->currency))) 
        {
            log_error("agency:%s,username:%s,currency:%s,account_currency:%s", agency.c_str(), username.c_str(),currency.c_str(), st_agency->currency.c_str()); 
            return;
        }
        RequestRechargeCb(account->uid, amount * st_agency->currency_unit_multi, st_agency->currency, trans, request_time, extra * st_agency->currency_unit_multi,
            account->agency_id, username, isfirst, balance * st_agency->currency_unit_multi);
    }
    else
    {
        StreamData stream_data;
        StreamDataWriter writer(stream_data);
        writer.WriteInt64(request_time);
        writer.Write<double>(amount);
        writer.WriteString(agency);
        writer.WriteString(username);
        writer.WriteString(currency);
        writer.WriteInt(account->uid);
        writer.WriteString(trans);
        writer.Write<double>(extra);
        writer.WriteBool(isfirst);
        writer.Write<double>(balance);
        

        if (!AgencyEventService::Instance()->HandleGetAgencyEvent(account->agency_id, std::move(stream_data.Data()), reinterpret_cast<std::uint64_t>(sence_recharge_cb)))
        {
            log_error("agency_id:%u,get agency_id failed", account->agency_id);
            return;
        }
    }
}
void ActionEventCb::OnRechargeCbAgencyEventGet(std::int32_t err_code, stAgencyEvent* st_agency, std::string&& trans)
{
    StreamData stream_data(std::move(trans));
    StreamDataReader reader(stream_data);
    std::uint64_t request_time = reader.ReadInt64();
    double amount = reader.Read<double>();
    std::string agency = reader.ReadString();
    std::string username = reader.ReadString();
    std::string currency = reader.ReadString();
    std::uint32_t uid = reader.ReadInt();
    trans = reader.ReadString();
    double extra = reader.Read<double>();
    bool isfirst = reader.ReadBool();
    double balance = reader.Read<double>();

    log_debug("err_code:%d,request_time:%llu,agency:%s,username:%s,amount:%f,currency:%s,uid:%u,extra:%f,isfirst:%d,balance:%f"
        , err_code,request_time,agency.c_str(),username.c_str(),amount,currency.c_str(), uid, extra, isfirst, balance);

    if (err_code != 0) { log_error("agency:%s,username:%s,err_code:%d", agency.c_str(), username.c_str(), err_code); return; }
    if (st_agency == nullptr) { log_error("agency:%s,username:%s", agency.c_str(), username.c_str()); return; }

    RequestRechargeCb(uid, amount * st_agency->currency_unit_multi, st_agency->currency, trans, request_time, extra * st_agency->currency_unit_multi,
        st_agency->agency_id, username, isfirst, balance * st_agency->currency_unit_multi);
}
int ActionEventCb::RequestRechargeCb(std::uint32_t uid, std::int64_t amount, const std::string& currency, const std::string& trans, std::uint64_t request_time, std::int64_t extra,
        std::uint32_t agency_id, const std::string& username, bool isfirst, std::int64_t balance)
{
    log_debug("uid:%u,amount:%d,currency:%s,request_time:%llu,extra:%ld,agency_id:%d,username:%s,isfirst:%d,balance:%ld", uid, amount, currency.c_str(), request_time,extra,agency_id,username.c_str(),isfirst,balance);
    unsigned int cmd = match_user::MATCH_USER_MSGID_USER_RECHARGE_NOTIFY;
    unsigned short dsttype = SERVER_TYPE_MATCH_USER;
    match_user::UserRechargeNotice notice;
    notice.set_uid(uid);
    notice.set_amount(amount);
    notice.set_trans(trans);
    notice.set_extra(extra);
    notice.set_agency_id(agency_id);
    notice.set_user_name(username);
    notice.set_isfirst(isfirst);
    notice.set_balance(balance);

    int ret = Ctx.host->MtSendtoSrv(cmd, dsttype, &notice, uid);
    if (0 != ret)
    {
        log_error("MtSendtoSrv cmd:%u, dst:%u, error:%d,uid:%u,amount:%lld,currency:%s", cmd, dsttype, ret, uid, amount, currency.c_str());
    }
    else
    {
        log_debug("MtSendtoSrv cmd:%u, dst:%u, error:%d,uid:%u,amount:%lld,currency:%s", cmd, dsttype, ret, uid, amount, currency.c_str());
    }
    return 0;
}







void ActionEventCb::HandleRegisterCb(HttpData&& data)
{
    std::int32_t err = 1;
    std::string msg = "";
    std::uint64_t request_time = CTools::GetUnixTimeMs();
    do
    {
        log_info("request_id:%d, ip:%s, target:%s, body:%s"
            ,data.request_id, data.ip.c_str(), data.target.c_str(), data.body.c_str());

        Json::Value json;
        if (!CTools::FromStr(json, data.body)) { msg="parser json failed"; break; } 
        /*
        req_id:xxx, agency_name:xxx, user_name:xxx, game_id:xxx, share_type:xxx
        */
        if (!json.isMember("agency_name") || !json["agency_name"].isString()) { msg="miss agency_name"; break; } 
        if (!json.isMember("user_name") || !json["user_name"].isString()) { msg="miss user_name"; break; }
        if (!json.isMember("game_id") || !json["game_id"].isInt()) { msg="miss game_id"; break; }
        if (!json.isMember("share_type") || !json["share_type"].isInt()) { msg="miss share_type"; break; } 

        std::string agency_name = json["agency_name"].asString();
        std::string user_name = json["user_name"].asString();
        std::int32_t game_id = json["game_id"].asInt();
        std::int32_t share_type = json["share_type"].asInt();

        if (agency_name.empty()) { msg="agency_name error"; break; }
        if (user_name.empty()) { msg="user_name error"; break; }
        
        std::int32_t agency_id = 0;
        {
            stAgencyEvent* temp = AgencyEventMgr::Instance()->GetAgencyId(agency_name);
            temp == nullptr ? agency_id=0: agency_id=temp->agency_id;
        }
        if (agency_id == 0)
        {
            log_error("agency_id not found! agency_name:%s;", agency_name.c_str());

            StreamData stream_data;
            StreamDataWriter writer(stream_data);
            writer.WriteInt64(request_time);
            writer.WriteString(user_name);
            writer.WriteInt(game_id);
            writer.WriteInt(share_type);
            
            if (!AgencyEventService::Instance()->HandleGetAgencyId(agency_name, std::move(stream_data.Data()), reinterpret_cast<std::uint64_t>(sence_register_cb)))
            {
                log_error("get agency_id falie, agency_name:%s, get agency_id failed", agency_name.c_str());
                break;
            }
        }
        else
        {
            err = 0;
            RequestRegisterCb(user_name, agency_id, game_id, share_type);
        }
    } while (false);

    // 错误码失败输出
    if (err != 0)
    {
        log_error("request_id:%d, ip:%s, target:%s, body:%s, err:%d, msg:%s", data.request_id, data.ip.c_str(), data.target.c_str(), data.body.c_str(), err, msg.c_str());
    }
    Response(data.request_id, request_time, err, msg);
}
void ActionEventCb::OnRegisterCbAgencyEventGet(std::int32_t err_code, stAgencyEvent* st_agency, std::string&& trans)
{
    log_debug("enter");
    StreamData stream_data(std::move(trans));
    StreamDataReader reader(stream_data);

    std::uint64_t request_time = reader.ReadInt64();
    std::string user_name = reader.ReadString();
    std::int32_t game_id = reader.ReadInt();
    std::int32_t share_type = reader.ReadInt();

    log_debug("err_code:%d, request_time:%llu, agency_id:%d ,user_name:%s, game_id:%d, share_type:%d;"
        ,err_code , request_time, st_agency->agency_id, user_name.c_str(), game_id, share_type);

    if (err_code != 0) { log_error("agency:%s, username:%s, err_code:%d", st_agency->agency_name.c_str(), user_name.c_str(), err_code); return; }
    if (st_agency == nullptr) { log_error("agency:%s, username:%s", st_agency->agency_name.c_str(), user_name.c_str()); return; }

    RequestRegisterCb(user_name, st_agency->agency_id, game_id, share_type);
}
int ActionEventCb::RequestRegisterCb(const std::string& user_name, const std::int32_t& agency_id, const std::int32_t& game_id, const std::int32_t& share_type)
{
    log_debug("user_name:%s, agency_id:%d, game_id:%d, share_type:%d;"
        ,user_name.c_str(), agency_id, game_id, share_type);
    
    unsigned int cmd = match_user::MATCH_USER_MSGID_GUEST_INVITEE_NOTIFY;
    unsigned short dsttype = SERVER_TYPE_MATCH_USER;
    match_user::GuestPkgInviteeNotice notice;

    notice.set_user_name(user_name);
    notice.set_agency_id(agency_id);
    notice.set_game_id(game_id);
    notice.set_share_type(share_type);

    int ret = Ctx.host->MtSendtoSrv(cmd, dsttype, &notice, 0);// 0成功 -1失败
    if (ret == -1)
    {
        log_error("MtSendtoSrv cmd:%u, dsttype:%u, ret:%d, error:%d, user_name:%s, agency_id:%d, game_id:%d, share_type:%d;"
            , cmd, dsttype, ret, user_name.c_str(), agency_id, game_id, share_type);
    }
    else
    {
        log_debug("MtSendtoSrv cmd:%u, dsttype:%u, ret:%d, user_name:%s, agency_id:%d, game_id:%d, share_type:%d;"
            , cmd, dsttype, ret, user_name.c_str(), agency_id, game_id, share_type);
    }
    return 0;
}




